package com.pokermind.dse.tcp.service;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pokermind.common.util.JsonUtil;
import com.pokermind.dse.tcp.protocol.ProtocolConstants;
import com.pokermind.dse.tcp.protocol.ProtocolMessage;
import com.pokermind.dse.tcp.util.ResponseWrapper;
import com.pokermind.common.context.RequestContext;
import com.pokermind.model.dto.*;
import com.pokermind.operator.AdvancedHandOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;

/**
 * Hand Management Service 手牌管理服务，处理TCP协议的手牌相关业务
 *
 * 支持的协议： - CREATE_HAND_REQ (1001) - 创建手牌 - UPDATE_HERO_CARDS_REQ (1002) - 更新Hero底牌 - TRANSITION_STREET_REQ (1003) -
 * 街道转换 - RECORD_ACTION_REQ (1004) - 记录行动 - COMPLETE_HAND_REQ (1005) - 完成手牌
 *
 * 与HTTP服务共享业务逻辑，通过AdvancedHandOperator处理
 *
 * @author PokerMind Team
 */
@Service
public class HandManagementService {

    private static final Logger logger = LoggerFactory.getLogger(HandManagementService.class);

    @Autowired
    private AdvancedHandOperator advancedHandOperator;

    private final ObjectMapper objectMapper =
        new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    @PostConstruct
    public void initialize() {
        logger.info("HandManagementService initialized");
    }

    /**
     * 处理手牌管理协议消息
     */
    public ProtocolMessage processMessage(ProtocolMessage message) {
        short protocolId = message.getProtocolId();

        // 设置请求上下文信息用于业务层日志追踪
        setupRequestContext(message);

        if (logger.isDebugEnabled()) {
            logger.debug("Processing hand management message: {} from {}", message.getProtocolName(),
                message.getClientId());
        }

        try {
            switch (protocolId) {
                case ProtocolConstants.CREATE_HAND_REQ:
                    return handleCreateHand(message);
                case ProtocolConstants.UPDATE_HERO_CARDS_REQ:
                    return handleUpdateHeroCards(message);
                case ProtocolConstants.TRANSITION_STREET_REQ:
                    return handleTransitionStreet(message);
                case ProtocolConstants.RECORD_ACTION_REQ:
                    return handleRecordAction(message);
                case ProtocolConstants.COMPLETE_HAND_REQ:
                    return handleCompleteHand(message);
                default:
                    logger.warn("Unsupported hand management protocol: {} from {}", message.getProtocolName(),
                        message.getClientId());
                    return ResponseWrapper.createErrorResponse(message, 4001, "unsupported_protocol");
            }
        } catch (Exception e) {
            logger.error("Error processing hand management message {}: {}", message.getProtocolName(), e.getMessage(),
                e);
            return ResponseWrapper.createBusinessErrorResponse(message, "hand_management_error", e.getMessage());
        } finally {
            // 清理请求上下文
            RequestContext.clear();
        }
    }

    /**
     * 设置请求上下文信息
     */
    private void setupRequestContext(ProtocolMessage message) {
        try {
            // 提取客户端RequestId
            String requestId = ResponseWrapper.extractClientRequestId(message);
            if (requestId != null) {
                RequestContext.setRequestId(requestId);
            }

            // 设置连接ID - 优先使用客户端发送的connId
            String connectionId = extractClientConnectionId(message);
            if (connectionId == null) {
                // 如果客户端没有发送connId，使用默认的网络连接标识
                connectionId = message.getClientId();
            }
            if (connectionId != null) {
                RequestContext.setConnectionId(connectionId);
            }

            // V4.7: 设置请求内容（不格式化，保持单行）
            String requestContent = message.getJsonBody();
            if (requestContent != null) {
                RequestContext.setRequestContent(requestContent);
            }

        } catch (Exception e) {
            // 如果提取失败，记录警告但不影响业务处理
            logger.warn("Failed to setup request context from message: {}", e.getMessage());
        }
    }

    /**
     * 从请求消息中提取客户端连接ID
     */
    private String extractClientConnectionId(ProtocolMessage message) {
        try {
            if (message.getJsonNode() != null && message.getJsonNode().has("connId")) {
                String connId = message.getJsonNode().get("connId").asText();
                logger.debug("Extracted connId from JsonNode: {}", connId);
                return connId;
            } else if (message.getJsonBody() != null) {
                JsonNode jsonNode = objectMapper.readTree(message.getJsonBody());
                if (jsonNode.has("connId")) {
                    String connId = jsonNode.get("connId").asText();
                    logger.debug("Extracted connId from JsonBody: {}", connId);
                    return connId;
                }
                logger.debug("No connId found in JsonBody: {}",
                    message.getJsonBody().length() > 100 ? message.getJsonBody().substring(0, 100) + "..."
                        : message.getJsonBody());
            }
        } catch (Exception e) {
            logger.warn("Failed to extract client connection ID: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 处理创建手牌请求
     */
    private ProtocolMessage handleCreateHand(ProtocolMessage message) throws Exception {
        // 解析新格式请求（提取业务数据）
        CreateHandRequest request = ResponseWrapper.extractBusinessData(message, CreateHandRequest.class);

        // 调用业务逻辑
        CreateHandResponse response = advancedHandOperator.createHand(request);

        // V4.10: 返回包含基本信息字段的完整响应
        return ResponseWrapper.createSuccessResponse(message, "success", response);
    }

    /**
     * 处理更新Hero底牌请求 - V4.1已废弃，保留用于向后兼容
     * @deprecated V4.1中已移除Hero概念，此接口仅保留兼容性
     */
    @Deprecated
    private ProtocolMessage handleUpdateHeroCards(ProtocolMessage message) throws Exception {
        // V4.1: 此接口已废弃，直接返回成功
        logger.warn("UpdateHeroCards接口已在V4.1废弃，请使用AI分析时直接提供hole_cards");
        return ResponseWrapper.createSuccessResponse(message, "deprecated - use AI analysis with hole_cards", null);
    }

    /**
     * 处理街道转换请求 - V4.1使用hand_id
     */
    private ProtocolMessage handleTransitionStreet(ProtocolMessage message) throws Exception {
        // V4.1: 直接从DTO中提取hand_id
        StreetTransitionRequest request = ResponseWrapper.extractBusinessData(message, StreetTransitionRequest.class);

        // 调用业务逻辑（V4.1：使用hand_id）
        StreetTransitionResponse response = advancedHandOperator.transitionToStreet(request.getHandId(), request);

        // V4.10: 返回包含基本信息字段的完整响应
        return ResponseWrapper.createSuccessResponse(message, "success", response);
    }

    /**
     * 处理记录行动请求 - V4.1使用hand_id
     */
    private ProtocolMessage handleRecordAction(ProtocolMessage message) throws Exception {
        // V4.1: ActionRequest已包含hand_id，直接提取
        ActionRequest request = ResponseWrapper.extractBusinessData(message, ActionRequest.class);

        // 调用业务逻辑（V4.1：使用hand_id）
        ActionResponse response = advancedHandOperator.recordAction(request.getHandId(), request);

        // V4.10: 返回包含基本信息字段的完整响应
        return ResponseWrapper.createSuccessResponse(message, "success", response);
    }

    /**
     * 处理完成手牌请求 - V4.1使用hand_id
     */
    private ProtocolMessage handleCompleteHand(ProtocolMessage message) throws Exception {
        // V4.1: HandCompletionRequest已包含hand_id，直接提取
        HandCompletionRequest request = ResponseWrapper.extractBusinessData(message, HandCompletionRequest.class);

        // 调用业务逻辑（V4.1：使用hand_id）
        HandCompletionResponse response = advancedHandOperator.completeHand(request.getHandId(), request);

        // V4.10: 返回包含基本信息字段的完整响应
        return ResponseWrapper.createSuccessResponse(message, "success", response);
    }

    /**
     * 获取业务数据节点 期望JSON格式: {"requestId": 123, "data": {...}}
     */
    private JsonNode getBusinessDataNode(ProtocolMessage message) throws Exception {
        JsonNode jsonNode = message.getJsonNode();
        if (jsonNode == null) {
            jsonNode = objectMapper.readTree(message.getJsonBody());
        }

        // 新格式必须包含data字段
        if (!jsonNode.has("data")) {
            throw new IllegalArgumentException("Request missing 'data' field: protocol=" + message.getProtocolName());
        }

        JsonNode dataNode = jsonNode.get("data");
        if (dataNode == null || dataNode.isNull()) {
            throw new IllegalArgumentException("Request 'data' field is null: protocol=" + message.getProtocolName());
        }

        return dataNode;
    }

}
